package vn.lumi.smarthome.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;



import vn.lumi.smarthome.LumiHome;
import vn.lumi.smarthome.R;
import vn.lumi.smarthome.network.*;
import vn.lumi.smarthome.ui.LoginActivity;
import vn.lumi.smarthome.ui.MainActivity;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
import android.widget.Toast;

public class SmartHomeService extends Service{
		
	//msg code for intents from UI
	public static final int UI2SER_NEW_MSG = 0;
	public static final int UI2SER_RECONNECT_HC = 1;
	public static final int UI2SER_END_APPLICATION = 2;
	public static final int SER2UI_MSG_SUCCESSFUL = 3;
	public static final int SER2UI_MSG_FAILED = 4;
	public static final int SER2UI_NEW_DEVICE_STATUS = 5;
	public static final int SER2UI_ALL_DEVICE_STATUS = 6;
	public static final int SER2UI_NEW_CONFIG = 7; 
	
	//msg code from threads
	public static final int SER2TRAN_NEW_MSG = 20;
	public static final int SER2TRAN_END_THREAD = 21;
	public static final int SER2TRAN_RESET = 22;
	
	public static final int SER2RECEI_END_THREAD = 30;
	public static final int SER2RECEI_RESET = 31;
	public static final int RECEI2SER_NEW_MSG = 32;
	
	public static final int RECON2SER_SUCESSFUL = 40;
	public static final int RECON2SER_FAILED_NONETWORK = 41;
	public static final int RECON2SER_FAILED_CANNOT_CONNECT = 42;
	public static final int RECON2SER_FAILED_SESSION_DELETED = 43;
	
	//register as clients
	public static final int MSG_REGISTER_CLIENT = 50;
	public static final int MSG_UNREGISTER_CLIENT = 51;
	
	//display toast
	public static final int MSG_DISPLAY_TOAST = 60;
	public static final String ToastTextKey = "Text for Toast";
	
	public static final String MESSAGE = "Msg";
	public static final String TIMEOUT = "Timeout";
	public static final String RETRY = "Retry";
	
	private ArrayList<Message2HC> Msg2HC=new ArrayList<Message2HC>();
	private final Messenger mMessenger = new Messenger(new IncomingMessageHandler()); // Target we publish for clients to send messages to IncomingHandler.
	private List<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.

	private Handler toastHandler = null; 
	ReceiveDataThread receiveThread = null;
	TransmitThread transmitThread = null;
	
	static LumiHome myApp;
	//socket
	
	public Handler mHandler;
	
	public static boolean isRunning = false;
	
	private int current_Msg_id = 1;
	private Timer keepAliveTimer = null;
	
	@Override
	public IBinder onBind(Intent intent) {
		return mMessenger.getBinder();
	}
	
	public static boolean isRunning()
	{
		return isRunning;
	}
	
	@SuppressLint("HandlerLeak")
	@Override
	public void onCreate() {
		isRunning = true;
		myApp = (LumiHome) getApplication();
		mHandler = new IncomingMessageHandler();
		Log.d("Service", " created");
		receiveThread = new ReceiveDataThread(LumiHome.is, mHandler);
		receiveThread.start();
		transmitThread = new TransmitThread(myApp, mHandler);
		transmitThread.start();	
		
		//display toast
		toastHandler = new Handler(){
			public void handleMessage(Message msg){
				if(msg.what == MSG_DISPLAY_TOAST){
					
					Bundle b = msg.getData();
					int textID = b.getInt(ToastTextKey);
					DisplayToast(textID, 1500);
				}
			}
		};
		
		//keepalive
		keepAliveTimer = new Timer();
		keepAliveTimer.scheduleAtFixedRate(new TimerTask() {				
			@Override
			public void run() {	
				if(isRunning == false)
					this.cancel();
				else{
					if(LumiHome.SocketState!= LumiHome.SOCKET_RECONNECTING){
						KeepAlive keepAlive = new KeepAlive(0, LumiHome.Uid, LumiHome.Session_id);
	                	//Create a new Msg2HC
	                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, keepAlive, LumiHome.Timeout);
	                	current_Msg_id ++;
	                	if(current_Msg_id > 250) current_Msg_id = 1;
	                	Msg2HC.add(Msg);
	                	Log.d("Service", "KeepAlive created");
	                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
	                	Msg.startTimer();
					}
				}
			}
		}, 30000, 120000);
	}

	@Override
	public void onDestroy() {
//		Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
		Log.d("Service", "stop now, bye bye!!!");
		if (keepAliveTimer != null) {keepAliveTimer.cancel();}
		isRunning = false;
		try{
			LumiHome.os.close();
			LumiHome.is.close();
			LumiHome.socket.close();
		}
		catch(Exception e){
			e.printStackTrace();
		}
		super.onDestroy();
		
	}
	
	@Override
	public void onStart(Intent intent, int startid) {
//		Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
	}
	
	@SuppressLint("HandlerLeak")
	class IncomingMessageHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 1000:
            	Log.d("Service", "CP :End app");
            	break;
            case UI2SER_END_APPLICATION:
//            	Log.d("Service", "CP: end application");
//            	receiveThread.End();
//            	transmitThread.End();
//            	isRunning = false;
//            	stopService();
            	break;
            case UI2SER_NEW_MSG:
            	//Take out the message
            	Bundle b = new Bundle();
            	b = msg.getData();
            	int MsgType = b.getInt("Message Type");
            	if(MsgType == NetMessage.CMD_APP_CONTROL_NORMAL){
            		ControlNormalDevice appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = ControlNormalDevice");
                	//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
                	Msg.startTimer();
            	}
            	else if(MsgType == NetMessage.CMD_APP_CONTROL_RGB){
            		ControlRGB appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = ControlRGB");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_CREATE_SCENE){
            		CreateScene appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = CreateModifyScene");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_ACTIVATE_SCENE){
            		TurnOnScene appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = ActivateScene");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_EDIT_SCENE){
            		EditScene appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = EditScene");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_DEL_SCENE){
            		DelScene appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = DelScene");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_CREATE_SCHEDULE){
            		// Hieu sua
//            		DelScene appMsg = b.getParcelable("ContentProvider Message");
            		CreateSchedule appMsg = b.getParcelable("ContentProvider Message");
            		// end
            		Log.d("Service", "CP: New Msg, type = CreateSchedule");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_EDIT_SCHEDULE){
            		EditSchedule appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = EditSchedule");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if(MsgType == NetMessage.CMD_APP_DEL_SCHEDULE){
            		DelSchedule appMsg = b.getParcelable("ContentProvider Message");
            		Log.d("Service", "CP: New Msg, type = DelSchedule");
            		//Create a new Msg2HC
                	Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.d("Service", "Msg2HC buffer=" + Msg2HC.size());
            	}
            	else if (MsgType == NetMessage.CMD_APP_TOGGLE_SCHEDULE) {
					ToggleSchedule appMsg = b.getParcelable("ContentProvider Message");
					Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, appMsg, LumiHome.Timeout);
					current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
                	Log.e("ban tin", "CMD_TOOGLE");
				}
            	else if (MsgType == NetMessage.CMD_APP_CHANGE_PASSWORD) {
            		String pass = b.getString("PassWord");
            		ChangePassWord changPwd = new ChangePassWord(0, LumiHome.Uid, LumiHome.Session_id, pass);
            		Message2HC Msg = new Message2HC(getApplicationContext(), current_Msg_id, changPwd, LumiHome.Timeout);
                	current_Msg_id ++;
                	if(current_Msg_id > 250) current_Msg_id = 1;
                	Msg2HC.add(Msg);
                	Msg.startTimer();
					Log.e("testSmart","" + pass );
				}
        		break;
            case RECEI2SER_NEW_MSG:
                //Take out the message
            	Bundle b1 = new Bundle();
            	b1 = msg.getData();
            	byte[] content1 = b1.getByteArray(SmartHomeService.MESSAGE);
            	Log.d("Service", "HC: New Msg" + Arrays.toString(content1));
            	//check if this is a feedback message
            	boolean isFeedbackMsg = false;
            	boolean isHcBusying = false;
            	if(Msg2HC.size() != 0){
            		int i = 0;
            		while(i < Msg2HC.size()){
            			isFeedbackMsg = Msg2HC.get(i).isCorrectACK(content1);
            			if(isFeedbackMsg) break;
            			isHcBusying = Msg2HC.get(i).isBusyAck(content1);
            			i++;
            			if(isHcBusying) break;
            		}                		
            	}
            	
            	if(isFeedbackMsg == false && isHcBusying == false){
                	//if not feedback message
            		switch(NetMessage.getCmdId(content1)){
            		case NetMessage.CMD_HC_UPDATE_DEVICE_STATUS:
            			UpdateDeviceStatus update = new UpdateDeviceStatus(getApplicationContext());
                		if(update.isCorrectFormat(content1, content1.length)){
                			update.parseMessage(content1, content1.length);
                			update.doWhenReceived(getApplicationContext());
                			Log.e("ban tin", "update deivice status");
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCENE_INFO:
            			UpdateSceneInfo updateSceneInfo = new UpdateSceneInfo(LumiHome.Uid);
            			if(updateSceneInfo.isCorrectFormat(content1, content1.length)){
                			updateSceneInfo.parseMessage(content1, content1.length);
                			updateSceneInfo.doWhenReceived(getApplicationContext());
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCENE_ACTIVATED:
            			UpdateSceneActivated updateSceneActivated = new UpdateSceneActivated(LumiHome.Uid);
            			if(updateSceneActivated.isCorrectFormat(content1, content1.length)){
                			updateSceneActivated.parseMessage(content1, content1.length);
                			updateSceneActivated.doWhenReceived(getApplicationContext());
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCENE_DELETED:
            			UpdateSceneDeleted updateSceneDeleted = new UpdateSceneDeleted(LumiHome.Uid);
            			if(updateSceneDeleted.isCorrectFormat(content1, content1.length)){
            				updateSceneDeleted.parseMessage(content1, content1.length);
            				updateSceneDeleted.doWhenReceived(getApplicationContext());
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCHEDULE_INFO:
            			UpdateScheduleInfo updateScheduleInfo = new UpdateScheduleInfo(LumiHome.Uid);
            			if(updateScheduleInfo.isCorrectFormat(content1, content1.length)){
            				updateScheduleInfo.parseMessage(content1, content1.length);
            				updateScheduleInfo.doWhenReceived(getApplicationContext());
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCHEDULE_STATE:
            			UpdateScheduleState updateScheduleState = new UpdateScheduleState(LumiHome.Uid);
            			if(updateScheduleState.isCorrectFormat(content1, content1.length)){
            				updateScheduleState.parseMessage(content1, content1.length);
            				updateScheduleState.doWhenReceived(getApplicationContext());
                		}
                		break;
            		case NetMessage.CMD_HC_UPDATE_SCHEDULE_DELETED:
            			UpdateScheduleDeleted updateScheduleDeleted = new UpdateScheduleDeleted(LumiHome.Uid);
            			if(updateScheduleDeleted.isCorrectFormat(content1, content1.length)){
            				updateScheduleDeleted.parseMessage(content1, content1.length);
            				updateScheduleDeleted.doWhenReceived(getApplicationContext());
                		}
                		break;
            		}
            	}          	
                break;
            case MSG_REGISTER_CLIENT:
				mClients.add(msg.replyTo);
				Log.d("Service", "New client: " + msg.replyTo.getClass().getName());
				break;
			case MSG_UNREGISTER_CLIENT:
				mClients.remove(msg.replyTo);
				Log.d("Service", "Remove client: " + msg.replyTo.getClass().getName());
				break;
            case RECON2SER_SUCESSFUL:
            	LumiHome.SocketState = LumiHome.SOCKET_OPENED;
            	Log.d("Service", "Reconnect Thread: Sucess, restart Receive Thread");
            	transmitThread.Restart();
                receiveThread.Restart();
                //UI
                DisplayHCReconnected();
                break;
            case RECON2SER_FAILED_CANNOT_CONNECT:
            	LumiHome.SocketState = LumiHome.SOCKET_CLOSED;
                //bao len UI
            	DisplayCannotConnectHC();
                break;
            case RECON2SER_FAILED_NONETWORK:
            	LumiHome.SocketState = LumiHome.SOCKET_CLOSED;
                //bao len UI
            	DisplayNoNetwork();
            	break;
            case RECON2SER_FAILED_SESSION_DELETED:
        	    //now destroy all activities and back to login window
            	Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            	intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
            			Intent.FLAG_ACTIVITY_NEW_TASK);
            	intent.putExtra("finish", true);
            	DisplayLoginAgain();
            	startActivity(intent);
            	break;
            default:
                super.handleMessage(msg);
            }
        }
	}
	
	private void DisplayNoNetwork(){
		DisplayToast(R.string.No_Wifi_3g, 1500);
//		Toast.makeText(this, R.string.No_Wifi_3g, Toast.LENGTH_LONG).show();
	}
	
	private void DisplayLoginAgain(){
		DisplayToast(R.string.txt_login_again, 1500);
	}
	
	public void DisplayToast(int textID, int miliseconds){
		final Toast toast = Toast.makeText(getApplicationContext(), textID, Toast.LENGTH_SHORT);
	    toast.show();
	
//	    Handler handler = new Handler();
//	        handler.postDelayed(new Runnable() {
//	           @Override
//	           public void run() {
//	               toast.cancel(); 
//	           }
//	    }, miliseconds);
	}
	
	private void DisplayHCReconnected(){

		DisplayToast(R.string.HC_Reconnected, 1500);
	}
	
	private void DisplayCannotConnectHC(){
		DisplayToast(R.string.Cannot_connect_HC, 1500);
	}
	
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d("Service","onStartCommand");
	    handleCommand(intent);
	    // We want this service to continue running until it is explicitly
	    // stopped, so return sticky.
		return startId;
	    
	}
	
	private void handleCommand(Intent i){
		
	}
	

	private void sendMessageToHC(Message msg){
		transmitThread.getHandler().sendMessage(msg);		
	}
	
	public class Message2HC {
		
		public static final int MSG_STATE_WAIT_TRANSMIT = 2;
		public static final int MSG_STATE_TRANSMITTED = 1;
		public static final int MSG_STATE_RETRY1 = 3;
		public static final int MSG_STATE_RETRY2 = 4;
		public static final int MSG_STATE_SUCESSFUL = 5;
		public static final int MSG_STATE_FAILED = 6;
		
		private AppMsg appMsg;
		public int Timeout = 0;
//		public int MaxRetry = 0;
		public int RetryTimes = 0;
		public Timer timer = null;
		protected int Msg_state = 0;
		private Context mContext;
		
		public Message2HC(Context context, int Msg_id, AppMsg appMsg, int Timeout){			
			this.appMsg = appMsg;
			
//			appMsg.setMsg_id(Msg_id);
			this.appMsg.setMsg_id(Msg_id);
			
			this.Timeout = LumiHome.Timeout;
			this.Msg_state = MSG_STATE_WAIT_TRANSMIT;
			this.mContext = context;
		}
		
		private void removeFromList(ArrayList<Message2HC> MsgList){
			MsgList.remove(this);
		}
		
		
		public void startTimer(){
			this.Msg_state = MSG_STATE_WAIT_TRANSMIT;
			this.timer = new Timer();
			
			timer.scheduleAtFixedRate(new TimerTask() {				
				@Override
				public void run() {		
					if(LumiHome.SocketState == LumiHome.SOCKET_CLOSED){
						Msg_state = MSG_STATE_FAILED;
						appMsg.doIfSendFail(mContext);
						Log.d("Service","Socket is closed, try reconnect now, Send msg failed:" + Arrays.toString(appMsg.generateByteArray()));
						removeFromList(Msg2HC);
						reconnectHC();
						this.cancel();
						return;
					}
					else if(LumiHome.SocketState == LumiHome.SOCKET_RECONNECTING){
						Msg_state = MSG_STATE_FAILED;
						appMsg.doIfSendFail(mContext);
						Log.d("Service","Socket is closed, Send msg failed:" + Arrays.toString(appMsg.generateByteArray()));
						removeFromList(Msg2HC);
						this.cancel();
						return;
					}
					if(Msg_state == MSG_STATE_WAIT_TRANSMIT){
						final Message msg = Message.obtain();
						msg.what = SmartHomeService.SER2TRAN_NEW_MSG;
						Bundle b = new Bundle();
						b.putByteArray(SmartHomeService.MESSAGE, appMsg.generateByteArray());
						msg.setData(b);
						//send
						Log.d("Service", "Msg to Transmit Thread, time=1:" + Arrays.toString(appMsg.generateByteArray()));
						sendMessageToHC(msg);
						Msg_state = MSG_STATE_TRANSMITTED;
					}
					else if(Msg_state  == MSG_STATE_TRANSMITTED) {
						final Message msg = Message.obtain();
						msg.what = SmartHomeService.SER2TRAN_NEW_MSG;
						Bundle b = new Bundle();
						b.putByteArray(SmartHomeService.MESSAGE, appMsg.generateByteArray());
						msg.setData(b);
						//send
						Log.d("Service", "Msg to Transmit Thread, time=2:" + Arrays.toString(appMsg.generateByteArray()));
						sendMessageToHC(msg);
						Msg_state = MSG_STATE_RETRY1;
					}
					else if(Msg_state  == MSG_STATE_RETRY1) {
						final Message msg = Message.obtain();
						msg.what = SmartHomeService.SER2TRAN_NEW_MSG;
						Bundle b = new Bundle();
						b.putByteArray(SmartHomeService.MESSAGE, appMsg.generateByteArray());
						msg.setData(b);
						//send
						Log.d("Service", "Msg to Transmit Thread, time=3:" + Arrays.toString(appMsg.generateByteArray()));
						sendMessageToHC(msg);
						Msg_state = MSG_STATE_RETRY2;
					}
					else if(Msg_state  == MSG_STATE_RETRY2) {
						Msg_state = MSG_STATE_FAILED;
						appMsg.doIfSendFail(mContext);
						Log.d("Service","Send msg failed:" + Arrays.toString(appMsg.generateByteArray()));
						removeFromList(Msg2HC);
						reconnectHC();
						this.cancel();
					}
				}
			}, 0, this.Timeout);	
		}
		
		public boolean isCorrectACK(byte[] Msg){
			boolean result  = false;
			if(Msg == null)
				result = false;
			else if(appMsg.isCorrectReply(Msg, Msg.length)){
				result = true;
				this.Msg_state = MSG_STATE_SUCESSFUL;
				this.timer.cancel();
				Log.d("Service","Send msg successful:" + Arrays.toString(appMsg.generateByteArray()));
				appMsg.doIfSendSuccessful(mContext);
				//self destroy
				removeFromList(Msg2HC);
				Log.d("Service","Msg2HC buffer=" + Msg2HC.size());
			}
			return result;
		}
		public boolean isBusyAck(byte[]Msg){
			boolean result = false;
			
			if(Msg == null)
				result = false;
			else if (appMsg.isCorrectBusy(Msg, Msg.length)) {
				result =true;
				this.Msg_state = MSG_STATE_WAIT_TRANSMIT;
				Log.e("ban tin", "HC is busy");
			}
			return result;
		}
	}
		
	private void reconnectHC(){
		//Inform user
		Message msg = toastHandler.obtainMessage();
		msg.what = MSG_DISPLAY_TOAST;
		Bundle b= new Bundle();
		b.putInt(ToastTextKey, R.string.HC_Connection_broken);
		msg.setData(b);
		toastHandler.sendMessage(msg);
		//close socket
		try {
			LumiHome.socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Log.d("Service","Can not close socket");
			return;
		}
		LumiHome.SocketState = LumiHome.SOCKET_RECONNECTING;
		receiveThread.Pause();
		//reopen socket
		ReconnectThread reconnect  = new ReconnectThread(this.mHandler, this.getApplicationContext());
		reconnect.start();
	}
}
